﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Configuration;

namespace Kyoh.Lib.WinForms
{
    /// <summary>ユーザの入力内容を記憶するオプションの付いたダイアログ。</summary>
    public sealed partial class MemorizedConfirmationDialog : Form
    {
        private MemorizedConfirmationDialog(
            string text,
            string caption,
            MessageBoxButtons buttons,
            MessageBoxIcon icon,
            MessageBoxDefaultButton defaultButton)
        {
            InitializeComponent();

            Text = caption ?? string.Empty;
            label1.Text = text;
            SetButtons(buttons);
            SetIcon(icon);
            SelectDefaultButton(defaultButton);
        }

        private void SelectDefaultButton(MessageBoxDefaultButton defaultButton)
        {
            switch (defaultButton)
            {
                case MessageBoxDefaultButton.Button1:
                    button1.Select();
                    break;
                case MessageBoxDefaultButton.Button2:
                    button2.Select();
                    break;
                case MessageBoxDefaultButton.Button3:
                    button3.Select();
                    break;
            }
        }

        private void SetIcon(MessageBoxIcon icon)
        {
            Icon iconImage = null;
            switch (icon)
            {
                case MessageBoxIcon.Asterisk:
                    iconImage = SystemIcons.Asterisk;
                    break;
                case MessageBoxIcon.Error:
                    iconImage = SystemIcons.Error;
                    break;
                case MessageBoxIcon.Exclamation:
                    iconImage = SystemIcons.Exclamation;
                    break;
                case MessageBoxIcon.Question:
                    iconImage = SystemIcons.Question;
                    break;
                case MessageBoxIcon.None:
                    iconImage = null;
                    break;
            }
            if (iconImage == null)
            {
                pictureBox1.Visible = false;
                pictureBox1.Size = new Size(1, 1);
            }
            else
            {
                pictureBox1.Visible = true;
                pictureBox1.Size = iconImage.Size;
                pictureBox1.Image = iconImage.ToBitmap();
            }
        }

        private void SetButtons(MessageBoxButtons buttons)
        {
            switch (buttons)
            {
                case MessageBoxButtons.OK:
                    button1.DialogResult = DialogResult.OK;
                    button1.Text = Properties.MemConfDialResource.OK;
                    button2.Visible = false;
                    button3.Visible = false;
                    buttonsTableLayoutPanel.SetColumn(button2, 2);
                    buttonsTableLayoutPanel.SetColumn(button1, 3);
                    buttonsTableLayoutPanel.SetColumn(button3, 4);
                    break;
                case MessageBoxButtons.OKCancel:
                    button1.DialogResult = DialogResult.OK;
                    button1.Text = Properties.MemConfDialResource.OK;
                    button2.DialogResult = DialogResult.Cancel;
                    button2.Text = Properties.MemConfDialResource.Cancel;
                    Hide3rdButton();
                    break;
                case MessageBoxButtons.RetryCancel:
                    button1.DialogResult = DialogResult.Retry;
                    button1.Text = Properties.MemConfDialResource.Retry;
                    button2.DialogResult = DialogResult.Cancel;
                    button2.Text = Properties.MemConfDialResource.Cancel;
                    Hide3rdButton();
                    break;
                case MessageBoxButtons.YesNo:
                    button1.DialogResult = DialogResult.Yes;
                    button1.Text = Properties.MemConfDialResource.Yes;
                    button2.DialogResult = DialogResult.No;
                    button2.Text = Properties.MemConfDialResource.No;
                    Hide3rdButton();
                    break;
                case MessageBoxButtons.AbortRetryIgnore:
                    button1.DialogResult = DialogResult.Abort;
                    button1.Text = Properties.MemConfDialResource.Abort;
                    button2.DialogResult = DialogResult.Retry;
                    button2.Text = Properties.MemConfDialResource.Retry;
                    button3.DialogResult = DialogResult.Ignore;
                    button3.Text = Properties.MemConfDialResource.Ignore;
                    break;
                case MessageBoxButtons.YesNoCancel:
                    button1.DialogResult = DialogResult.Yes;
                    button1.Text = Properties.MemConfDialResource.Yes;
                    button2.DialogResult = DialogResult.No;
                    button2.Text = Properties.MemConfDialResource.No;
                    button3.DialogResult = DialogResult.Cancel;
                    button3.Text = Properties.MemConfDialResource.Cancel;
                    break;
            }
        }

        private void Hide3rdButton()
        {
            button3.Visible = false;
            buttonsTableLayoutPanel.SetColumn(button3, 2);
            buttonsTableLayoutPanel.SetColumn(button2, 5);
            buttonsTableLayoutPanel.ColumnStyles[4].SizeType = SizeType.AutoSize;
        }

        /// <summary>指定したテキスト、キャプション、ボタン、アイコン、既定のボタンを表示するメッセージ ボックスを表示します。</summary>
        /// <param name="setting">「今後このダイアログを表示しない」オプションの保存先となる System.Configuration.SettingPropertyValue。</param>
        /// <param name="owner">モーダル ダイアログ ボックスを所有する System.Windows.Forms.IWin32Window の実装。</param>
        /// <param name="text">メッセージ ボックスに表示するテキスト。</param>
        /// <param name="caption">メッセージ ボックスのタイトル バーに表示するテキスト。</param>
        /// <param name="buttons">メッセージ ボックスに表示されるボタンを指定する System.Windows.Forms.MessageBoxButtons 値の 1 つ。</param>
        /// <param name="icon">メッセージ ボックスに表示されるアイコンを指定する System.Windows.Forms.MessageBoxIcon 値の 1 つ。</param>
        /// <param name="defaultButton">メッセージ ボックスの既定のボタンを指定する System.Windows.Forms.MessageBoxDefaultButton 値の 1つ。</param>
        /// <returns>DialogResult 値のいずれか。</returns>
        /// <exception cref="System.ComponentModel.InvalidEnumArgumentException">buttons が System.Windows.Forms.MessageBoxButtons のメンバーではありません。またはicon が System.Windows.Forms.MessageBoxIcon のメンバーではありません。または指定した defaultButton が、System.Windows.Forms.MessageBoxDefaultButton のメンバーではありません。</exception>
        /// <exception cref="System.ArgumentException">buttons に、無効な System.Windows.Forms.MessageBoxButtons の組み合わせが指定されています。</exception>
        /// <exception cref="System.InvalidOperationException">setting が、System.Windows.Forms.DialogResult 型のプロパティではありませんでした。</exception>
        /// <exception cref="System.ArgumentNullException">setting が、<c>null</c>。</exception>
        public static DialogResult Show(
            SettingsPropertyValue setting,
            string text,
            string caption = null,
            MessageBoxButtons buttons = MessageBoxButtons.OK,
            MessageBoxIcon icon = MessageBoxIcon.None,
            MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1,
            IWin32Window owner = null)
        {
            if (setting == null)
                throw new ArgumentNullException("setting");
            if (setting.Property.PropertyType != typeof(DialogResult))
                throw new InvalidOperationException();
            if ((DialogResult)setting.PropertyValue == DialogResult.None)
            {
                using (var dialog = new MemorizedConfirmationDialog(text, caption, buttons, icon, defaultButton))
                {
                    var result = dialog.ShowDialog(owner);
                    if (dialog.checkBox1.Checked)
                        setting.PropertyValue = result;
                    return result;
                }
            }
            return (DialogResult)setting.PropertyValue;
        }
    }
}
